#include "usart.h"

// ------------------------USART1部分--------------------------------------------

void USARTx_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
		
  RCC_AHB1PeriphClockCmd(USARTx_RX_GPIO_CLK | USARTx_TX_GPIO_CLK, ENABLE);

  /* 使能 USART 时钟 */
  USARTx_CLOCKCMD(USARTx_CLK, ENABLE);
  
  /* GPIO初始化 */
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;  
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  
  /* 配置Tx引脚为复用功能 */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Pin =  USARTx_TX_PIN;  
  GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStructure);

  /* 配置Rx引脚为复用功能 */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Pin =  USARTx_RX_PIN;
  GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStructure);
  
  /* 连接 PXx 到 USARTx_Tx */
  GPIO_PinAFConfig(USARTx_RX_GPIO_PORT, USARTx_RX_SOURCE, USARTx_RX_AF);

  /* 连接 PXx 到 USARTx__Rx */
  GPIO_PinAFConfig(USARTx_TX_GPIO_PORT, USARTx_TX_SOURCE, USARTx_TX_AF);
  

  USART_InitStructure.USART_BaudRate = USARTx_BAUDRATE;
  /* 字长(数据位+校验位)：8 */
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;	
  /* 停止位：1个停止位 */
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  /* 校验位选择：偶校验 */  
	USART_InitStructure.USART_Parity = USART_Parity_No;
  /* 硬件流控制：不使用硬件流 */
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  /* USART模式控制：同时使能接收和发送 */
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  /* 完成USART初始化配置 */
  USART_Init(USARTx, &USART_InitStructure); 
	
  /* 使能串口 */
  USART_Cmd(USARTx, ENABLE);
}

// 重定向c库函数printf到串口，重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
		/* 发送一个字节数据到串口 */
		USART_SendData(USARTx, (uint8_t) ch);
		
		/* 等待发送完毕 */
		while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);		
	
		return (ch);
}

// 重定向c库函数scanf到串口，重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
		/* 等待串口输入数据 */
		while (USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) == RESET);

		return (int)USART_ReceiveData(USARTx);
}

// ------------------------USART2部分--------------------------------------------

// 应该是int转字符的函数
static char *itoa(int value, char *string, int radix)
{
    int i, d;
    int flag = 0;
    char *ptr = string;

    if(radix != 10)
    {
        *ptr = 0;
        return string;
    }

    if(!value)
    {
        *ptr++ = 0x30;
        *ptr = 0;
        return string;
    }

    if(value < 0)
    {
        *ptr++ = '-';
        value *= -1;
    }
    for(i = 10000; i > 0; i /= 10)
    {
        d = value/i;
        if(d || flag)
        {
            *ptr++ = (char)(d+0x30);
            value -= (d * i);
            flag = 1;
        }
    }

    *ptr = 0;

    return string;
}

void USART2_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
	
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
  
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_5;  
  GPIO_Init(GPIOD, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6;
  GPIO_Init(GPIOD, &GPIO_InitStructure);
  
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_USART2);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_USART2);
  
  USART_InitStructure.USART_BaudRate = 115200;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;	
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  
	USART_Init(USART2, &USART_InitStructure); 
  USART_Cmd(USART2, ENABLE);
}

void USART2_Printf(unsigned char *Data, ...)
{
	const char *s;
	int d;
	char buf[16];
	va_list ap;
	va_start(ap, Data);
	while(*Data != 0)
	{
			if(*Data == 0x5c)// '\'
			{
					 switch(*++Data)
					 {
					 case 'r':
							 USART_SendData(USART2, 0x0d);// 回车符
							 Data++;
							 break;
					 case 'n':
							 USART_SendData(USART2, 0x0a);// 换行符
							 Data++;
							 break;
					 default:
							 Data++;
							 break;
						}
			 }
			 else if(*Data == '%')
			 {
					 switch(*++Data)
					 {
					 case 's':// 字符串
							 s = va_arg(ap, const char *);
							 for(; *s; s++)
									 USART_SendData(USART2, *s);
							 Data++;
							 break;
					 case 'd':
							 d = va_arg(ap, int);
							 itoa(d, buf, 10);
							 for(s = buf; *s; s++)
									 USART_SendData(USART2, *s);
							 Data++;
							 break;
					 default:
							 Data++;
							 break;
					 }
			 }
			 else 
				 USART_SendData(USART2, *Data++);
	}
}

// ------------------------USART3部分--------------------------------------------

void USART3_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
	
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
  
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10;  
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3);
  
  USART_InitStructure.USART_BaudRate = 115200;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;	
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	
  USART_Init(USART3, &USART_InitStructure); 
  USART_Cmd(USART3, ENABLE);
}

void USART3_Printf(unsigned char *Data, ...)
{
	const char *s;
	int d;
	char buf[16];
	va_list ap;
	va_start(ap, Data);
	while(*Data != 0)
	{
			if(*Data == 0x5c)// '\'
			{
					 switch(*++Data)
					 {
					 case 'r':
							 USART_SendData(USART3, 0x0d);// 回车符
							 Data++;
							 break;
					 case 'n':
							 USART_SendData(USART3, 0x0a);// 换行符
							 Data++;
							 break;
					 default:
							 Data++;
							 break;
						}
			 }
			 else if(*Data == '%')
			 {
					 switch(*++Data)
					 {
					 case 's':// 字符串
							 s = va_arg(ap, const char *);
							 for(; *s; s++)
									 USART_SendData(USART3, *s);
							 Data++;
							 break;
					 case 'd':
							 d = va_arg(ap, int);
							 itoa(d, buf, 10);
							 for(s = buf; *s; s++)
									 USART_SendData(USART3, *s);
							 Data++;
							 break;
					 default:
							 Data++;
							 break;
					 }
			 }
			 else 
				 USART_SendData(USART3, *Data++);
	}
}
